/*
 * DA4.c
 *
 * Created: 3/25/2014 2:43:56 PM
 *  Author: tawataob
 */ 


#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 1000000UL //fclk = 1MHz
#include <util/delay.h>

void red_on()		//slowly increases the duty cycle of the red
{
	for (int i=26; i<230; i++)
	{
		OCR0B = i;
		_delay_ms(6);
	}
}

void red_off()		// slowly decreases the duty cycle of the red
{
	for (int i=230; i>0; i--)
	{
		OCR0B = i;
		_delay_ms(6);
	}
}

void green_on()		// slowly increases the duty cycle of the green
{
	for (int i=26; i<230; i++)
	{
		OCR0A = i;
		_delay_ms(6);
	}
}

void green_off()	// slowly decreases the duty cycle of the green
{
	for (int i=230; i>0; i--)
	{
		OCR0A = i;
		_delay_ms(6);
	}
}

void blue_on()		// slowly increases the duty cycle of the blue
{
	for (int i=26; i<230; i++)
	{
		OCR2A = i;
		_delay_ms(6);
	}
}

void blue_off()		// slowly decreases the duty cycle of the blue
{
	for (int i=230; i>0; i--)
	{
		OCR2A = i;
		_delay_ms(6);
	}
}

void change_duty_cycle(int pwm)		// this function changes the prescalers of both timer0 and timer2, thereby changing the duty cycles.
{
	if(pwm == 0)
	{
		TCCR0B = 0x01; // timer0: no prescaling
		TCCR2B = 0x01; // timer2: no prescaling
	}
	if(pwm == 1)
	{
		TCCR0B = 0x02; // timer0 prescaler = 8
		TCCR2B = 0x02; // timer2 prescaler = 8
	}
	
	if(pwm == 2)
	{
		TCCR0B = 0x03; // timer0 prescaler = 64
		TCCR2B = 0x03; // timer2 prescaler = 32
	}
	if(pwm == 3)
	{
		TCCR0B = 0x04; // timer0 prescaler = 256
		TCCR2B = 0x04; // timer2 prescaler = 64
	}
}

int main(void)
{
	TCCR0A = 0xA3;	// sets timer0 on (Compare Output Mode, Fast PWM Mode using both OC0A and OC0B) also sets WGM to 011 for Fast PWM
	TCCR0B = 0x01;	// sets no prescaler and sets the last WGM bit to 0 for fast PWM
	TCCR2A = 0x83;	// sets timer2 on (Compare Output Mode, Fast PWM Mode using OCR2A) also sets WGM to 011 for Fast PWM
	TCCR2B = 0x01;	// sets no prescaler and sets the last WGM bit for fast PWM
	
	DDRD = ((1<<PORTD6)|(1<<PORTD5));		// set PD6 and PD5 to output
	DDRB = (1<<PORTB3);						// set PB3 to output
	
	while(1)
	{
		int delay = 300;
		int pwm = 0;
		red_on();		// R	- 100
		_delay_ms(delay);
		green_on();		// RG	- 110
		_delay_ms(delay);
		red_off();		// G	- 010
		_delay_ms(delay);
		blue_on();		// GB	- 011
		_delay_ms(delay);
		green_off();	// B	- 001
		_delay_ms(delay);
		red_on();		// RB	- 101
		_delay_ms(delay);
		green_on();		// RGB	- 111
		_delay_ms(delay);
						// all combinations have been displayed
		blue_off();
		red_off();
		green_off();
		
		change_duty_cycle(pwm);		// this section of code changes the duty cycle of the pwm
		pwm++;						// there are 4 different pwm modes in this program
		if(pwm == 3)
		pwm = 0;

	}
}
